<script setup>
import { onMounted, onUnmounted, ref, watch, nextTick, computed } from "vue";
import * as echarts from "echarts";
import { useScaleStore } from "@/stores/scaleStore";

const props = defineProps({
  title: {
    type: String,
    default: "垂直剖面图",
  },
  gridData: {
    type: Array,
    default: () => [],
  },
  point: {
    type: Object,
    default: () => ({}),
  },
  additionalInfo: {
    type: String,
    default: "",
  },
  closeEvent: Function,
  dataType: {
    type: String,
    default: "salinity",
    validator: (value) => ["salinity", "temperature"].includes(value),
  },
});

const closeClick = () => {
  props?.closeEvent();
};

let profileChart = null;
let resizeObserver = null;
const chartDom = ref(null);
const boxWrapRef = ref(null);
const headerRef = ref(null);
const isDragging = ref(false);
const startPos = ref({ x: 0, y: 0 });
const currentPos = ref({ x: 0, y: 0 });
const currentScale = ref(1);
const isResizing = ref(false);
const resizeDirection = ref(null);
const startSize = ref({ width: 700, height: 600 });
const currentSize = ref({ width: 700, height: 600 });

const scaleStore = useScaleStore();

watch(
  () => scaleStore.currentScale,
  (newScale) => {
    currentScale.value = newScale || 1;
  },
  { immediate: true }
);

const colorSchemes = {
  1: {
    color: "#FF6B6B",
    unit: "°C",
    xAxisName: "温度",
  },
  2: {
    color: "#4D96FF",
    unit: "PSU",
    xAxisName: "盐度",
  },
};

const currentScheme = computed(() => colorSchemes[props.dataType]);

const handleMouseDown = (e) => {
  if (e.target.classList.contains("resize-handle")) {
    isResizing.value = true;
    resizeDirection.value = e.target.dataset.direction;
    startSize.value = { ...currentSize.value };
    startPos.value = { x: e.clientX, y: e.clientY };

    e.stopPropagation();
    e.preventDefault();
    document.addEventListener("mousemove", handleResizeMove);
    document.addEventListener("mouseup", handleResizeEnd);
    return;
  }

  if (!headerRef.value || !headerRef.value.contains(e.target)) return;

  const adjustedX = e.clientX / currentScale.value;
  const adjustedY = e.clientY / currentScale.value;

  isDragging.value = true;
  startPos.value = {
    x: adjustedX - currentPos.value.x,
    y: adjustedY - currentPos.value.y,
  };

  e.stopPropagation();
  e.preventDefault();

  document.addEventListener("mousemove", handleMouseMove);
  document.addEventListener("mouseup", handleMouseUp);
};

const handleMouseMove = (e) => {
  if (!isDragging.value) return;

  const adjustedX = e.clientX / currentScale.value;
  const adjustedY = e.clientY / currentScale.value;

  const newX = adjustedX - startPos.value.x;
  const newY = adjustedY - startPos.value.y;

  currentPos.value = { x: newX, y: newY };

  if (boxWrapRef.value) {
    boxWrapRef.value.style.left = `${newX}px`;
    boxWrapRef.value.style.top = `${newY}px`;
  }

  e.preventDefault();
};

const handleMouseUp = () => {
  isDragging.value = false;
  document.removeEventListener("mousemove", handleMouseMove);
  document.removeEventListener("mouseup", handleMouseUp);
};

const handleResizeMove = (e) => {
  if (!isResizing.value) return;

  const deltaX = (e.clientX - startPos.value.x) / currentScale.value;
  const deltaY = (e.clientY - startPos.value.y) / currentScale.value;

  const newSize = { ...currentSize.value };

  switch (resizeDirection.value) {
    case "e":
      newSize.width = Math.max(400, startSize.value.width + deltaX);
      break;
    case "s":
      newSize.height = Math.max(300, startSize.value.height + deltaY);
      break;
    case "se":
      newSize.width = Math.max(400, startSize.value.width + deltaX);
      newSize.height = Math.max(300, startSize.value.height + deltaY);
      break;
  }

  currentSize.value = newSize;
  updateChartSize();
  e.preventDefault();
};

const handleResizeEnd = () => {
  isResizing.value = false;
  resizeDirection.value = null;
  document.removeEventListener("mousemove", handleResizeMove);
  document.removeEventListener("mouseup", handleResizeEnd);
};

const updateChartSize = () => {
  if (profileChart) {
    profileChart.resize();
  }
};

watch(
  () => [props.gridData, props.dataType],
  () => {
    if (props.gridData?.length) {
      renderProfile();
    }
  },
  { immediate: true, deep: true }
);

onMounted(async () => {
  await initChart();
  if (boxWrapRef.value) {
    const rect = boxWrapRef.value.getBoundingClientRect();
    currentPos.value = { x: rect.left, y: rect.top };
  }
});

async function initChart() {
  await nextTick();
  if (!chartDom.value) return;

  profileChart = echarts.init(chartDom.value);
  window.addEventListener("resize", () => {
    profileChart?.resize();
  });

  resizeObserver = new ResizeObserver(() => {
    profileChart?.resize();
  });
  resizeObserver.observe(chartDom.value);

  if (props.gridData?.length) {
    renderProfile();
  }
}

function processGridData() {
  if (!props.gridData?.length) {
    return { seriesData: [], depthData: [] };
  }

  const seriesData = [];
  const depthData = [];

  props.gridData.forEach((depthLayer) => {
    const depthKey = Object.keys(depthLayer)[0];
    const points = depthLayer[depthKey];

    if (points.length > 0) {
      const point = points[0];
      if (
        point?.high !== undefined &&
        point?.high !== null &&
        point?.value !== undefined &&
        point?.value !== null
      ) {
        depthData.push(Math.abs(point.high));
        seriesData.push(point.value);
      }
    }
  });

  return { seriesData, depthData };
}

function renderProfile() {
  if (!profileChart || !props.gridData?.length) {
    return;
  }

  try {
    const { seriesData, depthData } = processGridData();

    // 计算X轴范围
    const validValues = seriesData.filter((v) => v !== null && v !== undefined);
    let xMin, xMax;

    if (validValues.length === 0) {
      xMin = 0;
      xMax = 1;
    } else {
      const minValue = Math.min(...validValues);
      const maxValue = Math.max(...validValues);

      if (minValue === maxValue) {
        xMin = minValue - Math.abs(minValue * 0.1);
        xMax = maxValue + Math.abs(maxValue * 0.1);
        if (minValue === 0) {
          xMin = -1;
          xMax = 1;
        }
      } else {
        const rangePadding = (maxValue - minValue) * 0.1;
        xMin = minValue - rangePadding;
        xMax = maxValue + rangePadding;
      }
    }

    const option = {
      title: {
        text: props.title || currentScheme.value.xAxisName + "垂直剖面",
        left: "center",
        textStyle: {
          color: "#FFFFFF",
          fontSize: 20,
          fontWeight: "bold",
          fontFamily: "Microsoft YaHei, sans-serif",
        },
        subtext: `经度: ${
          props.point?.longitude?.toFixed(4) || "--"
        }°E  纬度: ${props.point?.latitude?.toFixed(4) || "--"}°N`,
        subtextStyle: {
          color: "#B8E1FF",
          fontSize: 14,
          fontFamily: "Microsoft YaHei, sans-serif",
        },
      },
      tooltip: {
        trigger: "axis",
        backgroundColor: "rgba(0, 20, 40, 0.9)",
        borderColor: "#4D96FF",
        borderWidth: 1,
        textStyle: {
          color: "#FFFFFF",
          fontSize: 14,
        },
        formatter: function (params) {
          const data = params[0].data;
          return `深度: ${data[1].toFixed(2)}m<br>${
            currentScheme.value.xAxisName
          }: ${data[0].toFixed(2)} ${currentScheme.value.unit}`;
        },
      },
      grid: {
        left: "3%",
        right: "4%",
        bottom: "3%",
        top: "15%",
        containLabel: true,
      },
      xAxis: {
        type: "value",
        name: currentScheme.value.xAxisName + `(${currentScheme.value.unit})`,
        nameLocation: "middle",
        nameGap: 25,
        min: xMin,
        max: xMax,
        axisLabel: {
          color: "#D9E6FF",
          fontSize: 14,
          fontFamily: "Microsoft YaHei, sans-serif",
        },
        nameTextStyle: {
          color: "#FFFFFF",
          fontSize: 14,
          fontWeight: "bold",
          fontFamily: "Microsoft YaHei, sans-serif",
        },
        axisLine: {
          lineStyle: {
            color: "#4D96FF",
            width: 2,
          },
        },
        splitLine: {
          lineStyle: {
            color: "rgba(77, 150, 255, 0.3)",
            type: "dashed",
          },
        },
      },
      yAxis: {
        type: "value",
        name: "深度(m)",
        inverse: true,
        axisLabel: {
          color: "#D9E6FF",
          fontSize: 14,
          fontFamily: "Microsoft YaHei, sans-serif",
        },
        nameTextStyle: {
          color: "#FFFFFF",
          fontSize: 14,
          fontWeight: "bold",
          fontFamily: "Microsoft YaHei, sans-serif",
        },
        axisLine: {
          lineStyle: {
            color: "#4D96FF",
            width: 2,
          },
        },
        splitLine: {
          lineStyle: {
            color: "rgba(77, 150, 255, 0.3)",
            type: "dashed",
          },
        },
      },
      series: [
        {
          name: currentScheme.value.xAxisName,
          type: "line",
          data: seriesData.map((value, index) => [value, depthData[index]]),
          symbol: "circle",
          symbolSize: 8,
          itemStyle: {
            color: currentScheme.value.color,
          },
          lineStyle: {
            color: currentScheme.value.color,
            width: 3,
          },
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: currentScheme.value.color + "AA",
              },
              {
                offset: 1,
                color: currentScheme.value.color + "20",
              },
            ]),
          },
          smooth: true,
        },
      ],
    };

    profileChart.setOption(option, true);
  } catch (error) {
    console.error("渲染剖面图表时出错:", error);
  }
}

onUnmounted(() => {
  if (resizeObserver) {
    resizeObserver.disconnect();
  }
  if (profileChart) {
    profileChart.dispose();
    profileChart = null;
  }
  document.removeEventListener("mousemove", handleMouseMove);
  document.removeEventListener("mouseup", handleMouseUp);
  document.removeEventListener("mousemove", handleResizeMove);
  document.removeEventListener("mouseup", handleResizeEnd);
});
</script>

<template>
  <div
    class="popup-container"
    :style="{
      left: `${currentPos.x}px`,
      top: `${currentPos.y}px`,
      width: `${currentSize.width}px`,
      height: `${currentSize.height}px`,
    }"
    :class="{ dragging: isDragging }"
  >
    <div class="pine"></div>
    <div class="box-wrap" ref="boxWrapRef">
      <div class="header-area" ref="headerRef" @mousedown="handleMouseDown">
        <div class="title-text">{{ title }}</div>
        <div class="close" @click="closeClick">×</div>
      </div>
      <div ref="chartDom" class="chart-container"></div>

      <div
        class="resize-handle resize-e"
        data-direction="e"
        @mousedown="handleMouseDown"
      ></div>
      <div
        class="resize-handle resize-s"
        data-direction="s"
        @mousedown="handleMouseDown"
      ></div>
      <div
        class="resize-handle resize-se"
        data-direction="se"
        @mousedown="handleMouseDown"
      ></div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.popup-container {
  position: fixed;
  z-index: 9999;
  cursor: default;
  min-width: 500px;
  min-height: 400px;
  font-family: "Microsoft YaHei", sans-serif;

  &.dragging {
    cursor: grabbing;
  }
}

.box-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 8px;
  border: 2px solid #4d96ff;
  background-color: rgba(10, 30, 60, 0.9);
  box-shadow: 0 0 15px 3px rgba(77, 150, 255, 0.6);
  animation: slide 0.5s;
  overflow: hidden;
  user-select: none;
}

.header-area {
  position: relative;
  height: 45px;
  background: linear-gradient(
    to right,
    rgba(15, 40, 80, 0.95),
    rgba(20, 50, 90, 0.95)
  );
  border-bottom: 1px solid #4d96ff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  cursor: grab;

  &:active {
    cursor: grabbing;
  }
}

.title-text {
  color: #ffffff;
  font-size: 18px;
  font-weight: bold;
  text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
}

.close {
  color: #d9e6ff;
  cursor: pointer;
  font-size: 22px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;

  &:hover {
    color: #ff6b6b;
    transform: scale(1.2);
  }
}

.chart-container {
  width: 100%;
  height: calc(100% - 45px);
  padding: 15px;
  box-sizing: border-box;
}

.resize-handle {
  position: absolute;
  background: transparent;
  z-index: 10;
}

.resize-e {
  cursor: e-resize;
  width: 10px;
  height: 100%;
  right: 0;
  top: 0;
}

.resize-s {
  cursor: s-resize;
  width: 100%;
  height: 10px;
  bottom: 0;
  left: 0;
}

.resize-se {
  cursor: se-resize;
  width: 16px;
  height: 16px;
  right: 0;
  bottom: 0;
  background: #4d96ff;
  opacity: 0;
  transition: opacity 0.2s;
}

.box-wrap:hover .resize-se {
  opacity: 1;
}

.pine {
  position: absolute;
  width: 100px;
  height: 100px;
  box-sizing: border-box;
  line-height: 120px;
  text-indent: 5px;
}

@keyframes slide {
  0% {
    opacity: 0;
    transform: translateY(20px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
